package edu.nf.llmtest.service.impl;

import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import edu.nf.llmtest.common.converter.SessionConverter;
import edu.nf.llmtest.common.enumeration.RedisKeyEnum;
import edu.nf.llmtest.mapper.SessionMapper;
import edu.nf.llmtest.model.document.SessionDoc;
import edu.nf.llmtest.model.entity.Session;
import edu.nf.llmtest.service.SessionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @ Author bin
 * @ Create  2025/11/3 上午8:56
 * 会话服务
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class SessionServiceImpl implements SessionService {
    private final SessionMapper sessionMapper;

    private final RedisTemplate<String, Object> redisTemplate;

    private final ElasticsearchOperations operations;

    private final SessionConverter sessionConverter;

    @Override
    public List<Session> getSessionByUserId(Integer userId) {
        List<Session> sessionList = new ArrayList<>();
        //先从缓存中获取
        List<Object> range = redisTemplate.opsForList().range(RedisKeyEnum.SESSIN_PERFIX.getValue() + userId, 0, -1);
        if (range != null){
            List<Session> finalSessionList = sessionList;
            range.forEach(item->{
                finalSessionList.add((Session) item);
            });
        }
        if (sessionList.isEmpty()){
            //缓存中没有，就从es里获取
            sessionList = getSessionDocByUserId(userId);
        }
        if (sessionList.isEmpty()){
            //es中没有，就从数据库中获取
            sessionList = sessionMapper.getSessionByUserId(userId);
        }
        return sessionList;
    }

    public List<Session> getSessionDocByUserId(Integer userId) {
        List<Session> sessionList = new ArrayList<>();
        NativeQueryBuilder queryBuilder = NativeQuery.builder();
        queryBuilder.withQuery(query ->
                query.bool(bool ->
                        bool.should(
                                QueryBuilders.term(term -> term.field("userId").value(userId))
                        )
                ));
        //执行查询并返回命中的结果
        SearchHits<SessionDoc> hits = operations.search(queryBuilder.build(), SessionDoc.class);
        //循环遍历命中的结果集
        hits.getSearchHits().forEach(hit -> {
            sessionList.add(sessionConverter.convertSession(hit.getContent()));
        });
        return sessionList;
    }
}
